import React from 'react';
import { Table, Input, Popconfirm, Form, Tooltip, Button, Tag } from 'antd';
import IconFont from '@/components/IconFont';
import CityPicker from '@/components/CityPicker';

import styles from './index.less';

const EditableContext = React.createContext();

const EditItem = props => {
    const { editing, dataIndex, title, record, index, children, ...restProps } = props;
    const context = React.useContext(EditableContext);
    const { form, data } = context;
    const { getFieldDecorator, getFieldsValue } = form;

    const getItem = () => {
        if (dataIndex === 'area') {
            return (
                <Form.Item style={{ margin: 0 }}>
                    {getFieldDecorator(dataIndex, {
                        initialValue: (record && record[dataIndex] && record[dataIndex].split(',')) || null,
                        rules: [
                            {
                                required: true,
                                message: '所在地区不能为空'
                            }
                        ]
                    })(
                        <CityPicker
                            valueType="codeArray"
                            style={{ width: '100%' }}
                            showSearch
                            placeholder="请选择所在地区"
                        />
                    )}
                </Form.Item>
            );
        }
        if (dataIndex === 'addressName') {
            const recordIndex = data.findIndex(item => item.key === record?.key);
            return (
                <Form.Item style={{ margin: 0 }}>
                    {getFieldDecorator(dataIndex, {
                        rules: [
                            {
                                required: true,
                                message: `请输入${title}!`,
                                whitespace: true
                            },
                            {
                                validator: (rule, value, callback) => {
                                    const formData = getFieldsValue();
                                    const isRepeat =
                                        data
                                            .filter((item, itemIndex) => {
                                                if (!item.addressName) {
                                                    return false;
                                                }
                                                return itemIndex !== recordIndex;
                                            })
                                            .map(item => item.addressName.trim())
                                            .indexOf(formData.addressName.trim()) > -1;
                                    if (formData.addressName && isRepeat) {
                                        callback('该办公地点已存在');
                                    }
                                    callback();
                                }
                            }
                        ],
                        initialValue: (record && record[dataIndex]) || ''
                    })(<Input placeholder={`请输入${title}`} maxLength={255} />)}
                </Form.Item>
            );
        }
        return (
            <Form.Item style={{ margin: 0 }}>
                {getFieldDecorator(dataIndex, {
                    rules: [
                        {
                            required: true,
                            message: `请输入${title}!`,
                            whitespace: true
                        }
                    ],
                    initialValue: (record && record[dataIndex]) || ''
                })(<Input placeholder={`请输入${title}`} maxLength={255} />)}
            </Form.Item>
        );
    };
    const renderCell = () => {
        if (editing) {
            return <td {...restProps}>{getItem()}</td>;
        }

        if (dataIndex === 'area') {
            const result = record[dataIndex]?.split(',') || [];
            return (
                <td {...restProps}>
                    <CityPicker valueType="codeArray" value={result} showOnly format="/" />
                </td>
            );
        }

        return <td {...restProps}>{children}</td>;
    };
    return <EditableContext.Consumer>{renderCell}</EditableContext.Consumer>;
};

const Editable = ({ form: tempForm, dataSource, onChange }, parentRef) => {
    const [data, setData] = React.useState(dataSource || []);
    const [editingKey, setEditingKey] = React.useState('');

    const isEditing = record => record.key === editingKey;
    React.useImperativeHandle(parentRef, () => ({
        isEditing: !!editingKey
    }));

    React.useEffect(() => {
        if (onChange) {
            onChange(data);
        }
        // eslint-disable-next-line react-hooks/exhaustive-deps
    }, [data]);

    React.useEffect(() => {
        setData(dataSource);
    }, [dataSource]);

    const handleSave = (form, key) => {
        tempForm.validateFields((error, row) => {
            if (error) {
                return;
            }
            const newData = [...data];
            const index = newData.findIndex(item => key === item.key);
            if (index > -1) {
                const item = newData[index];
                newData.splice(index, 1, {
                    ...item,
                    ...row,
                    area: row.area && row.area.length > 0 ? row.area.join(',') : ''
                });
            } else {
                newData.push(row);
            }
            setData(newData);
            setEditingKey('');
        });
    };

    const handleCancel = key => {
        const { addressName, area, addressDetail } = data.find(item => item.key === key);
        if (!(addressName || area || addressDetail)) {
            setData(data.filter(item => item.key !== key));
        }
        setEditingKey('');
    };

    const handleEdit = key => {
        setEditingKey(key);
    };

    const handleDelete = key => {
        const newData = [...data];
        const index = newData.findIndex(item => key === item.key);
        if (index > -1) {
            newData.splice(index, 1);
        }
        setData(newData);
        setEditingKey('');
    };

    const handleAdd = () => {
        const newData = [...data];
        const tempKey = new Date().getTime().toString();
        newData.push({
            key: tempKey,
            addressName: '',
            area: '',
            addressDetail: '',
            isDefault: 0
        });
        setData(newData);
        setEditingKey(tempKey);
    };

    const handleDefault = key => {
        const newData = data.map(item => {
            if (item.key === key) {
                return {
                    ...item,
                    isDefault: 1
                };
            }
            return {
                ...item,
                isDefault: 0
            };
        });
        setData(newData);
        setEditingKey('');
    };

    const columns = [
        {
            title: '名称',
            dataIndex: 'addressName',
            width: '20%',
            editable: true
        },
        {
            title: '所在地区',
            dataIndex: 'area',
            width: '27%',
            render: text => (text && text.split(',').join('/')) || text,
            editable: true
        },
        {
            title: '详细地址',
            dataIndex: 'addressDetail',
            width: '38%',
            render: (text, record) => {
                if (record.isDefault) {
                    return (
                        <>
                            <span>{text}</span>
                            <Tag color="orange" style={{ marginLeft: 10 }}>
                                通讯地址
                            </Tag>
                        </>
                    );
                }
                return <p>{text}</p>;
            },
            editable: true
        },
        {
            title: '操作',
            dataIndex: 'operation',
            width: '15%',
            render: (text, record) => {
                const editable = isEditing(record);
                return editable ? (
                    <span>
                        <EditableContext.Consumer>
                            {({ form }) => (
                                <Tooltip title="保存">
                                    <IconFont
                                        className={styles.iconButton}
                                        isButton
                                        onClick={() => handleSave(form, record.key)}
                                        icon="iconduigou"
                                    />
                                </Tooltip>
                            )}
                        </EditableContext.Consumer>
                        <Popconfirm title="确定取消吗？" onConfirm={() => handleCancel(record.key)}>
                            <Tooltip title="取消">
                                <IconFont className={styles.iconButton} isButton icon="iconoa_form_bnt_dele" />
                            </Tooltip>
                        </Popconfirm>
                    </span>
                ) : (
                    <>
                        <Tooltip title="编辑">
                            <IconFont
                                className={styles.iconButton}
                                isButton
                                disabled={editingKey !== ''}
                                onClick={() => handleEdit(record.key)}
                                icon="iconoa_maeu_icon_record_default"
                            />
                        </Tooltip>
                        <Popconfirm title="确定删除吗？" onConfirm={() => handleDelete(record.key)}>
                            <Tooltip title="删除">
                                <IconFont
                                    className={styles.iconButton}
                                    isButton
                                    disabled={editingKey !== ''}
                                    icon="iconicon_deletex"
                                />
                            </Tooltip>
                        </Popconfirm>
                        <Tooltip title="设为通讯地址">
                            <IconFont
                                isButton
                                className={styles.iconButton}
                                disabled={record.isDefault || editingKey !== ''}
                                onClick={() => handleDefault(record.key)}
                                icon="iconoa_icon_address_default"
                            />
                        </Tooltip>
                    </>
                );
            }
        }
    ];

    const realColumns = columns.map(col => {
        if (!col.editable) {
            return col;
        }
        return {
            ...col,
            onCell: record => ({
                record,
                dataIndex: col.dataIndex,
                title: col.title,
                editing: isEditing(record)
            })
        };
    });
    const components = {
        body: {
            cell: EditItem
        }
    };
    return (
        <EditableContext.Provider value={{ form: tempForm, data }}>
            <Table
                bordered={false}
                components={components}
                dataSource={data}
                columns={realColumns}
                rowClassName={styles.editableRow}
                pagination={false}
            />
            <Button
                type="dashed"
                icon="plus"
                block
                disabled={editingKey !== ''}
                style={{ margin: '10px 0' }}
                onClick={handleAdd}
            >
                新增地点
            </Button>
        </EditableContext.Provider>
    );
};

export default Form.create()(React.forwardRef(Editable));
